import wmi,gevent,subprocess,time,asyncio
from gevent.queue import Queue
import threading
from gevent import monkey
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor,wait,as_completed
import asyncio,socket
from multiprocessing import Process, Queue
import multiprocessing

import concurrent.futures as cf  # 多加一个模块
# monkey;monkey.patch_all() 
monkey.patch_all(thread=False,select=False)

list = []
ip_list = []
tasks = []
datas = []
id = 0

for s in range (1,100):
    for i in range (2,255):
        if i == 189:
            pass
        else:
            ip_list.append ('172.25.{}.{}'.format (s,i))
            
# for i in range (100,106):
    # if i == 189:
        # pass
    # else:
        # ip_list.append ('172.25.1.{}'.format (i))
        
# def ping_ip (ip):
    # res = subprocess.call ('ping -n 1 -w 5 %s' % ip,stdout=subprocess.PIPE) # windows 
    # if res == False:
        # list.append (ip)

def scan (ip):
    try:
        s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout (10)
        s.connect ((ip,3389))
        # print ('Ok')
        tasks.append (ip)
    except:
        # print ('none')
        pass 
    s.close ()
    
def collect (ip):
    # while not tasks.empty ():
        # ip = tasks.get ()
    try:
        # start_time = time.time ()
        wmi_obj = wmi.WMI (computer = ip,user = r'.\admin',password = '2018.pw.')
        if wmi_obj:
            data = {
                        'os_name':wmi_obj.Win32_ComputerSystem()[0].Name, # 显示系统名称 'SIT-I44987-O'
                        'os_system':wmi_obj.Win32_OperatingSystem()[0].Name [:24], # 显示操作系统 'Microsoft Windows 10
                        }
            # print (wmi_obj)
            data.update (get_cpu_info (wmi_obj))
            data.update (get_ram_info(wmi_obj))
            data.update (get_disk_info(wmi_obj))
            data.update (get_nic_info(wmi_obj))
            print (data)
            return data
            # print ('耗时{:.2f}'.format(time.time() - start_time))
    except:
        pass
        
def get_cpu_info (wmi_obj):
    """
    获取CPU的相关数据，这里只采集了三个数据，实际有更多，请自行选择需要的数据
    :return:
    """
    data = {}
    cpu_lists = wmi_obj.Win32_Processor()
    cpu_core_count = 0 
    for cpu in cpu_lists:
        cpu_core_count += cpu.NumberOfCores
        
    cpu_model = cpu_lists[0].Name # CPU型号（所有的CPU型号都是一样的）
    data ['cpu_cont'] = len (cpu_lists)  # CPU个数
    data ['cpu_model'] = cpu_model
    data ['cpu_core_count'] = cpu_core_count # CPU总的核数
    return data
    
def get_ram_info (wmi_obj):
    """
    收集内存信息
    :return:
    """
    data = []
    ram_collections = wmi_obj.Win32_PhysicalMemory()
    for ram in ram_collections:  # 主机中存在很多根内存，要循环所有的内存数据
        ram_size = int (int (ram.Capacity) / (1024**3)) # 转换内存单位为GB
        item_data = {
            'slot':ram.DeviceLocator.strip(),
            'capacity':ram_size,
            'model':ram.Caption,
            'manufacturer':ram.Manufacturer,
            'sn':ram.SerialNumber
            }
        data.append (item_data)  # 将每条内存的信息，添加到一个列表里
    return {'ram':data}   # 再对data列表封装一层，返回一个字典，方便上级方法的调用 

def get_disk_info (wmi_obj):
    """
    硬盘信息
    :return:
    """
    data = []
    for disk in wmi_obj.Win32_DiskDrive ():  # 每块硬盘都要获取相应信息
        disk_data = {}
        interface_choices = ['SAS','SCSI','SATA','SSD']
        for interface in interface_choices:
            if interface in disk.Model:
                disk_data ['interface_type'] = interface
                break 
            else:
                disk_data ['interface_type'] = 'unknown'
            
        disk_data ['slot'] = disk.index
        disk_data ['sn'] = disk.SerialNumber
        disk_data ['model'] = disk.Model
        disk_data ['manufacturer'] = disk.Manufacturer
        disk_data ['capacity'] =int (int (disk.Size) / (1024 **3))
        data.append (disk_data)
    
    return {'physical_disk_driver':data}
    
def get_nic_info (wmi_obj):
    """
    网卡信息
    :return:
    """
    data = []
    for nic in wmi_obj.Win32_NetworkAdapterConfiguration():
        if nic.MACAddress is not None:
            nic_data = {}
            nic_data['mac'] = nic.MACAddress
            nic_data ['model'] = nic.Caption
            nic_data['name'] = nic.Index
            if nic.IPAddress is not None:
                nic_data ['ip_address'] = nic.IPAddress[0]
                nic_data ['net_mask'] = nic.IPSubnet
            else:
                nic_data ['ip_address'] = ''
                nic_data ['net_mask'] = ''
            data.append (nic_data)
        
    return {'nic':data}
    
def aa ():
    pool = multiprocessing.Pool(60) # 开启最大进程，53秒左右,max_workers = (os.cpu_count() or 1) * 5
    data = pool.map(collect,[ip for ip in tasks])
    pool.close()
    pool.join()
    print (data)
        
# def bb ():
    # f_list = []
    # executor = ProcessPoolExecutor(max_workers=60)
    # for ip in tasks:
        # future = executor.submit (collect,ip)  # 开启最大进程，53秒左右, max_workers must be <= 61
        # f_list.append(future)
        
    # wait(f_list)
        
    # executor.map(collect,[ip for ip in tasks])
        
if __name__ == '__main__':
    start_time = time.time ()
    
    task = [gevent.spawn (scan,ip) for ip in ip_list]
    gevent.joinall (task)
    
    # threads = []
    # for ip in ip_list:
        # t = threading.Thread (target = scan,args = (ip,))
        # t.start ()
        # threads.append (t)
        
    # for th in threads:
        # th.join ()
             
    # print (tasks)
    # print (len (tasks))
    print ('ping执行-->耗时{:.2f}'.format(time.time() - start_time))
    
    # f_list = []
    # executor = ProcessPoolExecutor(max_workers=60)
    # for ip in tasks:
        # future = executor.submit (collect,ip)  # 开启最大进程，53秒左右, max_workers must be <= 61
        # f_list.append(future)
        
    # wait(f_list) # 默认采用ALL_COMPLETED，程序会阻塞直到线程池里面的所有任务都完成，再执行主线程
    aa ()
    
    print ('threadPool执行-->耗时{:.2f}'.format(time.time() - start_time))